package com.tedu.api.map;

import org.junit.jupiter.api.Test;
import sun.management.snmp.jvminstr.JvmOSImpl;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

/**包位置：java.util
 * Map与Collection同等级顶级接口
 * Map映射接口
 * 作用：一个元素有两个对象构成，分别为Key和Value构成，
 *      获取元素：采用键取值，通常与数据库搭配，获取字段下的值
 *      特点：无序，无下标，键不可以重复【唯一性】，值可以重复
 *
 *      Map接口---无法直接实例化【创建对象】---实现类
 *      HashMap【常用】：由哈希算法底层实现，存储性能快，键可以存null值，
 *      主要是通过键找值
 *      LinkedHashMap【不常用】：方法与HashMap，用于日志记录按照时间排序
 *      TreeMap【不用】：性能插入删除满，不安全，占用内存
 *      【算法：红黑树实现--需要进行树的旋转和调整以保持平衡】
 *      Hashtable【不用】：jdk1.0，性能：插入删除非常慢，多线程不安全，占用内存
 *                   【算法：哈希算法】
 *                  Hashtable已被ConcurrentHashMap取代
 *      ConcurrentHashMap【较为常用】：学习多线程
 *
 *      重点：Map接口中方法【Map接口方法与HashMap方法类似  90%】
 *       12个集合类【保存状态】---保存数据---操作：增删改查
 */
public class MapAPI {
    @Test
    public void testMap(){
        //创建Map映射接口---多态 键--->值  id--19870502
        Map<Object,String> map=new HashMap<>();
        //键--->值 添加元素：K-V
        /**
         * put("键","值")  返回值：V  value 值
         * 作用：存键值对形态一组数据
         */
        map.put("西游记","孙悟空");
        map.put("红楼梦","贾宝玉");
        map.put("水浒传","武松");
        map.put("梦","玉");
        System.out.println("map映射存储数据"+map);
        /**
         * get()    根据建找到对应值  返回值：V value
         * remove() 通过key删除一组键值对
         * size()
         */
        //找到map集合中 武松的元素 ---V value值
        String wusong=map.get("水浒传");
        System.out.println("通过键找到值："+wusong);
        //get()键不存在--返回值的默认值：基本类型，引用类型：null值
        String sunwukong=map.get("西游记");
        System.out.println("通过键找到值："+sunwukong);
        map.remove("三国志");
        System.out.println("删除后映射："+map);
        System.out.println("获取map元素总数"+map.size());
        /**
         * containKey()   返回值:boolean
         * 作用：判断map中元素 “对象：键“  是否存在
         * containsValue()  返回值：boolean
         * 作用：判断map中元素  ”对象：值“  是否存在
         */
        boolean bk=map.containsKey("红楼梦");
        System.out.println("map元素:键"+bk);
        boolean bv=map.containsKey("孙悟空1");
        System.out.println("map元素:值"+bv);
    }

        /**
         * map元素遍历   键：实际上是Set集合：--->值
         * keySet()    获取map元素中所有的键
         * values()    获取map元素中所有的值
         * entrySet()  获取map元素中所有的键与值
         */
        @Test
        public void testKVE(){
            //创建Map映射集合
            Map<Object, String> map = new HashMap<>();
            map.put("默", "那英");
            map.put("告白气球", "周杰伦");
            map.put("套马杆", "乌拉图雅");
            map.put("丑八怪", "薛之谦");
            //获取1.map集合元素中 键 数据 keySet()  返回值：Set集合
            Set<Object> set = map.keySet();
            for (Object keys : map.keySet()) {
                System.out.println("输出map元素中：" + keys);
            }
            //2.获取map集合元素中 值 数据 values() 返回值：Collection
            Collection<String> cs = map.values();
            //2.2遍历从map元素中获取的值--数据
            for (String values : cs) {
                System.out.println("输出map元素中" + values);
            }
            //3.获取map集合元素【entrys】中 数据：键与值 entrySet()
            //返回值：Set<map.entry<K,V>>
            //Map.Entry<K,V>  保存map元素一组数据，表示：一组entry
            Set<Map.Entry<Object,String>>entrys=map.entrySet();
            //获取map映射集合所有元素【entry】
            //3.1遍历map所有的键与值【所有entry/元素/数据--成对】
            for(Map.Entry<Object,String> entry:entrys){
                //3.2获取键  getKey   注意：类型
                Object keys=entry.getKey();
                //3.3获取值  getValue 注意：类型
                String values=entry.getValue();
                //3.4  打印
                System.out.println(keys+""+values);
            }
        }
    /**
     * forEach(new BiConsumer()) 遍历map中所有 对元素/entry
     * 理解：for+entrySet()集合+forEach()
     * Biconsumer接口参数 传入
     * 理解：针对map存储问题--封装接口--提供方法：accept() 所有entry
     */
    @Test
    public void testForEach(){
        //创建Map映射集合
        Map<Object, String> map = new HashMap<>();
        map.put("默", "那英");
        map.put("告白气球", "周杰伦");
        map.put("套马杆", "乌拉图雅");
        map.put("丑八怪", "薛之谦");
        //Map映射集合--提供一套方法：forEach()
        map.forEach(new BiConsumer<Object, String>() {
            //accept(K,V)方法：获取刀Entry中--每组entry
            //K--键  V--值
            public void accept(Object key, String value) {
                System.out.println(key+"1:"+value);
            }
        });
        }

    /**
     * HashMap 映射集合
     * HashMap中发给发基本与Map方法一致
     * putIfAbsent()
     * 作用：用来给HashMap映射集合存入【Entry/一组数据：一组键值】
     *      如果存入一组数据，不存在的键，插入HashMap
     *                     存在的键，不插入HashMap
     *      哈希算法--唯一性
     *
     */
    @Test
    public void testHashMap(){
        //创建Map映射集合
        Map<Object, String> map = new HashMap<>();
        map.put("默", "那英");
        map.put("告白气球", "周杰伦");
        map.put("套马杆", "乌拉图雅");
        map.put("丑八怪", "薛之谦");
        System.out.println("HashMap的值："+map);

    }
}

